﻿using DoNetDrive.Common.Extensions;
using DoNetDrive.Connector.WindowsBLE;
using DoNetDrive.Core;
using DoNetDrive.Core.Command.Byte;
using DoNetDrive.Core.Connector;
using DotNetty.Buffers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Windows.System;

namespace WinFormsBLETest
{
    public partial class Form2 : Form
    {
        private BLESearchService SearchService;

        private HashSet<ulong> BLEAddrs = new HashSet<ulong>();

        private ConnectorAllocator mConnectorAllocator;

        private ConnectorObserverHandler Observer;
        private BLEDetail ConnectDetail;
        public Form2()
        {
            InitializeComponent();

            mConnectorAllocator = ConnectorAllocator.GetAllocator();
            mConnectorAllocator.AddBLEConnectorFactory();
            mConnectorAllocator.ConnectorClosedEvent += MConnectorAllocator_ConnectorClosedEvent;

            Observer = new ConnectorObserverHandler();
            Observer.DisposeResponseEvent += Observer_DisposeResponseEvent;
            Observer.DisposeRequestEvent += Observer_DisposeRequestEvent;
        }

        private void MConnectorAllocator_ConnectorClosedEvent(object sender, INConnectorDetail connector)
        {
            AddLog($" {connector} 连接已断开 ");
            this.Invoke(() => {
                ConnectDetail = null;
                btnOpen.Enabled = true;
                btnClose.Enabled = false;
            });
        }

        /// <summary>
        /// 接收到数据回调
        /// </summary>
        /// <param name="connector"></param>
        /// <param name="msg"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void Observer_DisposeRequestEvent(INConnector connector, string msg)
        {
            AddLog("接收：" + msg);
        }

        /// <summary>
        /// 发送数据回调
        /// </summary>
        /// <param name="connector"></param>
        /// <param name="msg"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void Observer_DisposeResponseEvent(INConnector connector, string msg)
        {
            AddLog("发送：" + msg);
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (SearchService == null)
            {
                SearchService = new BLESearchService(SearchBLECallBlack);
            }
            ClearBLEDevice();
            var ret = SearchService.StartBleDeviceWatcher();
            if (ret == false)
            {
                AddLog("电脑可能不支持蓝牙或未开启蓝牙功能");
                var uri = new Uri("ms-settings-bluetooth:turnon");
                Launcher.LaunchUriAsync(uri);
                return;
            }
                

            btnSearch.Enabled = false;
            
            Task.Run(async () =>
            {
                await Task.Delay(15000);
                SearchService.StopBleDeviceWatcher();
                this.Invoke(() => btnSearch.Enabled = true);
            });
        }


        private class BLEItem
        {
            public ulong Addr;
            public string Name;
            public override string ToString()
            {
                return $"{Name} - {Addr:X12}";
            }
        }

        private void SearchBLECallBlack(ulong BLEAddr, string BLEName)
        {
            this.Invoke(() =>
            {
                if (!BLEAddrs.Contains(BLEAddr))
                {
                    if (!string.IsNullOrEmpty(BLEName))
                    {
                        var item = new BLEItem()
                        {
                            Addr = BLEAddr,
                            Name = BLEName
                        };
                        cmbBLEList.Items.Add(item);
                        BLEAddrs.Add(BLEAddr);
                        AddLog($"搜索到蓝牙设备：{item}");
                    }

                }
            });
        }

        private void ClearBLEDevice()
        {
            cmbBLEList.Items.Clear();
            BLEAddrs.Clear();
        }

        private void AddLog(string txt)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(() => AddLog(txt));
                return;
            }

            string sLog = $"{DateTime.Now:HH:mm:ss.fff} - {txt} \r\n";

            if (txtLog.TextLength > 20000)
            {
                txtLog.Text = txtLog.Text.Substring(10000);
            }

            txtLog.AppendText(sLog);


        }

        private async void btnOpen_Click(object sender, EventArgs e)
        {

            var item = cmbBLEList.SelectedItem as BLEItem;
            if (item == null)
            {
                ShowMsgBox("请选择需要连接的蓝牙设备名称！");
                return;
            }

            string sUUID = txtServiceUUID.Text;

            if (string.IsNullOrEmpty(sUUID))
            {
                ShowMsgBox("请输入要连接的蓝牙服务UUID！");
                return;
            }


            BLEDetail dtl = new BLEDetail(item.Addr, item.Name, sUUID);
            try
            {
                btnOpen.Enabled = false;

                var BLEConn = await mConnectorAllocator.OpenConnectorAsync(dtl) as BLEConnector;

                if (BLEConn == null) return;

                BLEConn.AddRequestHandle(Observer);

                ConnectDetail = dtl;

                AddLog("打开蓝牙设备连接成功！");
                
                btnClose.Enabled = true;
            }
            catch (Exception ex)
            {
                btnOpen.Enabled = true;
                AddLog("打开蓝牙设备连接时发生错误！" + ex.Message);
            }


        }
        private async void btnClose_Click(object sender, EventArgs e)
        {
            try
            {
                await mConnectorAllocator.CloseConnectorAsync(ConnectDetail);
                ConnectDetail = null;
                AddLog("关闭蓝牙设备连接成功！");
                btnOpen.Enabled = true;
                btnClose.Enabled = false;
            }
            catch (Exception ex)
            {

                AddLog("关闭蓝牙设备连接失败！" + ex.Message);
            }
        }

        private void ShowMsgBox(string sTxt)
        {
            MessageBox.Show("请选择需要连接的蓝牙设备名称！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private async void btnSend_Click(object sender, EventArgs e)
        {
            if (ConnectDetail == null)
            {
                ShowMsgBox("请先连接蓝牙！");
                return;
            }

            string txt = txtSendData.Text;
            if (string.IsNullOrEmpty(txt))
            {
                ShowMsgBox("请先输入待发送内容！");
                return;
            }

            byte[] sendBytes;
            if (chkHEX.Checked)
            {
                if (!txt.IsHex())
                {
                    ShowMsgBox("输入的内容不是十六进制，请重新输入！");
                    return;
                }
                if (chkNewline.Checked)
                {
                    byte[] hexBuf = txt.HexToByte();
                    byte[] newLinebytes = System.Text.Encoding.ASCII.GetBytes("\r\n");
                    sendBytes = hexBuf.Concat(newLinebytes).ToArray();
                }
                else
                    sendBytes = txt.HexToByte();



            }
            else
            {
                if (chkNewline.Checked)
                {
                    txt = txt + "\r\n";
                }
                sendBytes = System.Text.Encoding.ASCII.GetBytes(txt);
            }

            using ByteCommandDetail cmdDtl = new ByteCommandDetail(ConnectDetail);

            var buf = Unpooled.WrappedBuffer(sendBytes);
            using var par = new ByteCommandParameter(buf);
            using var cmd = new ByteCommand(cmdDtl, par);

            try
            {
                await mConnectorAllocator.AddCommandAsync(cmd);
                AddLog("发送完毕！");
            }
            catch (Exception ex)
            {

                AddLog("发送时发生错误：" + ex.Message);
            }


        }

        private void Form2_Load(object sender, EventArgs e)
        {

        }
    }
}
